package com.spzx.channel.service.Impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;

import com.spzx.channel.domain.ItemVo;
import com.spzx.channel.service.IItemService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.Product;
import com.spzx.product.api.domain.ProductDetails;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.vo.SkuPrice;
import com.spzx.product.api.domain.vo.SkuStockVo;
import jakarta.servlet.ServletException;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * projectName: spzx-parent
 *
 * @author: 王宝贵
 * time: 2024/10/9 19:25 周三
 * description:
 */
@Service
@Slf4j
public class ItemServiceImpl implements IItemService {

    @Autowired
    RemoteProductService remoteProductService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    /**
     * 查询商品详情信息
     * @param skuId skuId
     * @return
     */
    @Override
    public ItemVo item(Long skuId) throws RuntimeException {

        //先检验bloomFilter释放存在
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter("sku:bloom:filter");
        if(!bloomFilter.contains(skuId)){
            //不存在
            log.error("用户查询商品sku不存在：{}", skuId);
            //查询数据不存在直接返回空对象
            throw new ServiceException("用户查询商品sku不存在");
        }


        ItemVo itemVo = new ItemVo();
        //将itemVo塞满


        //1.productSku信息(开启线程池 需要返回结果)
        CompletableFuture<ProductSku> productSkuCompletableFuture = CompletableFuture.supplyAsync(() -> {
            R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (productSkuResult.getCode() == R.FAIL) {
                //异常
                try {
                    throw new ServletException("查询商品sku信息出错了：" + productSkuResult.getMsg());
                } catch (ServletException e) {
                    e.printStackTrace();
                }
            }
            ProductSku productSku = productSkuResult.getData();
            itemVo.setProductSku(productSku);

            return productSku;
        },threadPoolExecutor);


        //2.商品信息  商品轮播图列表信息  商品规格信息(使用返回结果消费 不要返回值 )

        CompletableFuture<Void> ProductCompletableFuture = productSkuCompletableFuture.thenAcceptAsync(productSku -> {
            R<Product> productR = remoteProductService.getProduct(productSku.getProductId(), SecurityConstants.INNER);
            if (productR.getCode() == R.FAIL) {
                //异常
                try {
                    throw new ServletException("查询商品sku信息出错了：" + productR.getMsg());
                } catch (ServletException e) {
                    e.printStackTrace();
                }
            }

            itemVo.setProduct(productR.getData());
            //商品轮播图列表信息
            List<String> SliderUrlList = Arrays.asList(productR.getData().getSliderUrls().split(","));
            itemVo.setSliderUrlList(SliderUrlList);
            //商品规格信息 TODO JSON格式的Array
            JSONArray specValueList = JSON.parseArray(productR.getData().getSpecValue());
            itemVo.setSpecValueList(specValueList);
        }, threadPoolExecutor);


        //3.最新价格信息(不使用等待返回值，也没有返回值)
        CompletableFuture<Void> skuPriceProductCompletableFuture = CompletableFuture.runAsync(() -> {
            R<SkuPrice> skuPriceR = remoteProductService.getSkuPrice(skuId, SecurityConstants.INNER);
            if (skuPriceR.getCode() == R.FAIL) {
                //异常
                try {
                    throw new ServletException("查询商品sku信息出错了：" + skuPriceR.getMsg());
                } catch (ServletException e) {
                    e.printStackTrace();
                }
            }
            itemVo.setSkuPrice(skuPriceR.getData());
        }, threadPoolExecutor);


        //4.商品详情图片列表(线程池  需要sku返回结果 也不需要返回结果)
        CompletableFuture<Void> productDetailsCompletableFuture = productSkuCompletableFuture.thenAcceptAsync(productSku -> {
            R<ProductDetails> productDetailsR = remoteProductService.getProductDetails(productSku.getProductId(), SecurityConstants.INNER);
            if (productDetailsR.getCode() == R.FAIL) {
                //异常
                try {
                    throw new ServletException("查询商品sku信息出错了：" + productDetailsR.getMsg());
                } catch (ServletException e) {
                    e.printStackTrace();
                }
            }
            String imageUrls = productDetailsR.getData().getImageUrls();
            //字符串转数组
            itemVo.setDetailsImageUrlList(Arrays.asList(imageUrls.split(",")));
        }, threadPoolExecutor);


        //5.商品库存信息(线程池 需要sku返回结果 也不需要返回结果)
        CompletableFuture<Void> skuStockProductCompletableFuture = productSkuCompletableFuture.thenAcceptAsync((productSku) -> {
            R<SkuStockVo> skuStockVoR = remoteProductService.getSkuStock(skuId, SecurityConstants.INNER);
            if (skuStockVoR.getCode() == R.FAIL) {
                //异常
                try {
                    throw new ServletException("查询商品sku信息出错了：" + skuStockVoR.getMsg());
                } catch (ServletException e) {
                    e.printStackTrace();
                }
            }
            //将商品sku信息里面的sku库存页加上
            productSku.setStockNum(skuStockVoR.getData().getAvailableNum());
            itemVo.setSkuStockVo(skuStockVoR.getData());
        }, threadPoolExecutor);


        //6.商品规格信息(线程池 需要sku返回结果 也不需要返回结果)
        CompletableFuture<Void> SkuSpecValueCompletableFuture = productSkuCompletableFuture.thenAcceptAsync(productSku -> {
            R<Map<String, Long>> skuSpecValueR = remoteProductService.getSkuSpecValue(productSku.getProductId(), SecurityConstants.INNER);
            if (skuSpecValueR.getCode() == R.FAIL) {
                //异常
                try {
                    throw new ServletException("查询商品sku信息出错了：" + skuSpecValueR.getMsg());
                } catch (ServletException e) {
                    e.printStackTrace();
                }
            }
            Map<String, Long> skuSpecValueMap = skuSpecValueR.getData();
            itemVo.setSkuSpecValueMap(skuSpecValueMap);
        }, threadPoolExecutor);

        //等待所有线程执行完毕
        CompletableFuture.allOf(
                productSkuCompletableFuture,
                ProductCompletableFuture,
                skuPriceProductCompletableFuture,
                productDetailsCompletableFuture,
                skuStockProductCompletableFuture,
                SkuSpecValueCompletableFuture)
                .join();

        //返回前端
        return itemVo;
    }
}